//
// Created by 34649 on 2022/3/1.
//
#include "include/http_server.h"
using namespace http;
http::http_server::http_server(EventLoop *loop, const InetAddress &listenAddr)
:loop_(loop),
 server_(loop,listenAddr,"http_server"){
    server_.setConnectionCallback(std::bind(&http_server::onConnection, this,_1));
    server_.setMessageCallback(std::bind(&http_server::onMessage,this,_1,_2,_3));
//    server_.setWriteCompleteCallback();
}

void http::http_server::start() {
    server_.start();
}

void http::http_server::onConnection(const TcpConnectionPtr &conn) {

}

void http::http_server::onMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp time) {
    //string msg(buf->retrieveAllAsString());
    //LOG_INFO<<msg;
    decoderPtr decoder;
    if(dmap.find(conn)!=dmap.end()){
        LOG_WARN<<"decoder found";
        decoder=dmap[conn];
    }else{
        decoder=std::make_shared<http_decoder>(buf);
        dmap[conn]=decoder;
    }
    LOG_INFO<<&decoder;
    HTTP_PARSE_CODE res;
    if((res=decoder->parse_http())!=HTTP_PARSE_CODE::OK){
        LOG_ERROR<<static_cast<int>(res);
        conn->disconnected();
    }else{
        if(decoder->status==HTTP_PARSE_STATUS::FINISHED){
            http_response response= handleRequest(decoder);
            LOG_INFO<<response.serialize();
            conn->send(response.serialize());
            if(decoder->keep_alived){//保持连接就初始化decoder,复用decoder
                decoder->init();
            }else{
                dmap.erase(conn);//不保持链接就断开链接,析构decoder
                conn->disconnected();
            }
        }else{
            LOG_WARN<<"parse not complete!";
        }
    }
}

void http_server::setRootPath(string path) {
    rootPath=path;
}

string http_server::getRootPath() {
    return rootPath;
}

http_response http_server::handleRequest(decoderPtr req) {
    http_response response;
    if(req->parse_code != HTTP_PARSE_CODE::OK){
        response.setHttpCode(HTTP_CODE::Bad_Request);
        return response;
    }
    if(req->getMethod() == METHOD::GET)return handleGetRequest(req);
}

http_response http_server::handleGetRequest(decoderPtr req) {
    http_response response;
    string path;
    path += rootPath;
    path += req->getUrl();
    response.setHeader("Content-Type","text/html;charset=utf-8");
    std::ifstream fin(path);
    if(!fin.good()){
        response.setHttpCode( HTTP_CODE::Not_Found);
        return response;
    }
    std::ostringstream tmp;
    tmp << fin.rdbuf();
    response.setContent(tmp.str());
    fin.close();
    return response;
}

